home *** CD-ROM | disk | FTP | other *** search
- /******************************************************************************
- * SBsp_Ref.c - Refinements for Tri-Variate Bsplines. *
- *******************************************************************************
- * Written by Gershon Elber, Sep. 94. *
- ******************************************************************************/
-
- #include <string.h>
- #include "triv_loc.h"
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Given a trivariate, refines it at the given n knots as defined by the M
- * vector t. M
- * If Replace is TRUE, the values replace the current knot vector. M
- * Returns pointer to refined TV (Note a Bezier trivariate will be M
- * converted into a Bspline trivariate). M
- * *
- * PARAMETERS: M
- * TV: Trivariate to refine according to t in direction Dir. M
- * Dir: Direction of refinement. Either U or V or W. M
- * Replace: If TRUE t is a knot vector exaclt in the length of the knot M
- * vector in direction Dir in TV and t simply replaces than knot M
- * vector. If FALSE, the knot vector in direction Dir in TV is M
- * refined by adding all the knots in t. M
- * t: Knot vector to refine/replace the knot vector of TV in M
- * direction Dir. M
- * n: Length of vector t. M
- * *
- * RETURN VALUE: M
- * TrivTVStruct *: The refined trivariate. Always a Bspline trivariate. M
- * *
- * KEYWORDS: M
- * TrivTVRefineAtParams, trivariates M
- *****************************************************************************/
- TrivTVStruct *TrivTVRefineAtParams(TrivTVStruct *TV,
- TrivTVDirType Dir,
- CagdBType Replace,
- CagdRType *t,
- int n)
- {
- TrivTVStruct *BspTV, *TTV;
-
- switch (TV -> GType) {
- case TRIV_TVBEZIER_TYPE:
- BspTV = TrivCnvrtBezier2BsplineTV(TV);
- TTV = TrivBspTVKnotInsertNDiff(BspTV, Dir, Replace, t, n);
- TrivTVFree(BspTV);
- return TTV;
- case TRIV_TVBSPLINE_TYPE:
- return TrivBspTVKnotInsertNDiff(TV, Dir, Replace, t, n);
- default:
- TRIV_FATAL_ERROR(TRIV_ERR_UNDEF_GEOM);
- return NULL;
- }
- }
-
- /*****************************************************************************
- * DESCRIPTION: M
- * Given a Bspline trivariate, inserts n knots with different values as M
- * defined by t. M
- * If, however, Replace is TRUE, the knot are simply replacing the current M
- * knot vector in the prescribed direction. M
- * *
- * PARAMETERS: M
- * TV: Trivariate to refine according to t in direction Dir. M
- * Replace: If TRUE t is a knot vector exaclt in the length of the knot M
- * vector in direction Dir in TV and t simply replaces than knot M
- * vector. If FALSE, the knot vector in direction Dir in TV is M
- * refined by adding all the knots in t. M
- * t: Knot vector to refine/replace the knot vector of TV in M
- * direction Dir. M
- * n: Length of vector t. M
- * *
- * RETURN VALUE: M
- * TrivTVStruct *: The refined trivariate. A Bspline trivariate. M
- * *
- * KEYWORDS: M
- * TrivBspTVKnotInsertNDiff, trivariates M
- *****************************************************************************/
- TrivTVStruct *TrivBspTVKnotInsertNDiff(TrivTVStruct *TV,
- TrivTVDirType Dir,
- int Replace,
- CagdRType *t,
- int n)
- {
- CagdBType
- IsNotRational = !TRIV_IS_RATIONAL_TV(TV);
- int i, ODim,
- ULength = TV -> ULength,
- VLength = TV -> VLength,
- WLength = TV -> WLength,
- UOrder = TV -> UOrder,
- VOrder = TV -> VOrder,
- WOrder = TV -> WOrder,
- MaxCoord = CAGD_NUM_OF_PT_COORD(TV -> PType);
- TrivTVStruct
- *RefTV = NULL;
-
- if (Replace) {
- for (i = 1; i < n; i++)
- if (t[i] < t[i - 1])
- TRIV_FATAL_ERROR(TRIV_ERR_KNOT_NOT_ORDERED);
-
- switch (Dir) {
- case TRIV_CONST_U_DIR:
- if (TV -> UOrder + TV -> ULength != n)
- TRIV_FATAL_ERROR(TRIV_ERR_NUM_KNOT_MISMATCH);
-
- RefTV = TrivTVCopy(TV);
- for (i = 0; i < n; i++)
- RefTV -> UKnotVector[i] = *t++;
- break;
- case TRIV_CONST_V_DIR:
- if (TV -> VOrder + TV -> VLength != n)
- TRIV_FATAL_ERROR(TRIV_ERR_NUM_KNOT_MISMATCH);
-
- RefTV = TrivTVCopy(TV);
- for (i = 0; i < n; i++)
- RefTV -> VKnotVector[i] = *t++;
- break;
- case TRIV_CONST_W_DIR:
- if (TV -> WOrder + TV -> WLength != n)
- TRIV_FATAL_ERROR(TRIV_ERR_NUM_KNOT_MISMATCH);
-
- RefTV = TrivTVCopy(TV);
- for (i = 0; i < n; i++)
- RefTV -> WKnotVector[i] = *t++;
- break;
- default:
- TRIV_FATAL_ERROR(TRIV_ERR_DIR_NOT_VALID);
- break;
- }
- }
- else if (n == 0) {
- RefTV = TrivTVCopy(TV);
- }
- else {
- int j, LengthKVt, RULength, RVLength, RWLength;
- BspKnotAlphaCoeffType *A;
- CagdRType *MergedKVt,
- *UKnotVector = TV -> UKnotVector,
- *VKnotVector = TV -> VKnotVector,
- *WKnotVector = TV -> WKnotVector;
-
- switch (Dir) {
- case TRIV_CONST_U_DIR:
- /* Compute the Alpha refinement matrix. */
- MergedKVt = BspKnotMergeTwo(UKnotVector, ULength + UOrder,
- t, n, 0, &LengthKVt);
- A = BspKnotEvalAlphaCoef(UOrder, UKnotVector, ULength,
- MergedKVt, LengthKVt - UOrder);
-
- RefTV = TrivBspTVNew(ULength + n, VLength, WLength,
- UOrder, VOrder, WOrder, TV -> PType);
- IritFree((VoidPtr) RefTV -> UKnotVector);
- IritFree((VoidPtr) RefTV -> VKnotVector);
- IritFree((VoidPtr) RefTV -> WKnotVector);
- RefTV -> UKnotVector = MergedKVt;
- RefTV -> VKnotVector = BspKnotCopy(TV -> VKnotVector,
- TV -> VLength + TV -> VOrder);
- RefTV -> WKnotVector = BspKnotCopy(TV -> WKnotVector,
- TV -> WLength + TV -> WOrder);
-
- RULength = RefTV -> ULength;
-
- /* Update the control mesh */
- for (ODim = 0; ODim < VLength * WLength; ODim++) {
- int OIndex = ODim * TRIV_NEXT_V(TV),
- ROIndex = ODim * TRIV_NEXT_V(RefTV);
-
- for (j = IsNotRational; j <= MaxCoord; j++) {
- CagdRType
- *ROnePts = &RefTV -> Points[j][ROIndex],
- *OnePts = &TV -> Points[j][OIndex];
-
- for (i = 0;
- i < RULength;
- i++, ROnePts += TRIV_NEXT_U(RefTV))
- CAGD_ALPHA_BLEND_STEP(A, i, OnePts,
- INFINITY,
- ROnePts, TRIV_NEXT_U(TV));
- }
- }
-
- BspKnotFreeAlphaCoef(A);
- break;
- case TRIV_CONST_V_DIR:
- /* Compute the Alpha refinement matrix. */
- MergedKVt = BspKnotMergeTwo(VKnotVector, VLength + VOrder,
- t, n, 0, &LengthKVt);
- A = BspKnotEvalAlphaCoef(VOrder, VKnotVector, VLength,
- MergedKVt, LengthKVt - VOrder);
-
- RefTV = TrivBspTVNew(ULength, VLength + n, WLength,
- UOrder, VOrder, WOrder, TV -> PType);
- IritFree((VoidPtr) RefTV -> UKnotVector);
- IritFree((VoidPtr) RefTV -> VKnotVector);
- IritFree((VoidPtr) RefTV -> WKnotVector);
- RefTV -> UKnotVector = BspKnotCopy(TV -> UKnotVector,
- TV -> ULength + TV -> UOrder);
- RefTV -> VKnotVector = MergedKVt;
- RefTV -> WKnotVector = BspKnotCopy(TV -> WKnotVector,
- TV -> WLength + TV -> WOrder);
-
- RULength = RefTV -> ULength;
- RVLength = RefTV -> VLength;
-
- /* Update the control mesh */
- for (ODim = 0; ODim < ULength * WLength; ODim++) {
- int OIndex = (ODim / ULength) * TRIV_NEXT_W(TV) +
- (ODim % ULength) * TRIV_NEXT_U(TV),
- ROIndex = (ODim / RULength) * TRIV_NEXT_W(RefTV) +
- (ODim % RULength) * TRIV_NEXT_U(RefTV);
-
- for (j = IsNotRational; j <= MaxCoord; j++) {
- CagdRType
- *ROnePts = &RefTV -> Points[j][ROIndex],
- *OnePts = &TV -> Points[j][OIndex];
-
- for (i = 0;
- i < RVLength;
- i++, ROnePts += TRIV_NEXT_V(RefTV))
- CAGD_ALPHA_BLEND_STEP(A, i, OnePts,
- INFINITY,
- ROnePts, TRIV_NEXT_V(TV));
- }
- }
-
- BspKnotFreeAlphaCoef(A);
- break;
- case TRIV_CONST_W_DIR:
- /* Compute the Alpha refinement matrix. */
- MergedKVt = BspKnotMergeTwo(WKnotVector, WLength + WOrder,
- t, n, 0, &LengthKVt);
- A = BspKnotEvalAlphaCoef(WOrder, WKnotVector, WLength,
- MergedKVt, LengthKVt - WOrder);
-
- RefTV = TrivBspTVNew(ULength, VLength, WLength + n,
- UOrder, VOrder, WOrder, TV -> PType);
- IritFree((VoidPtr) RefTV -> UKnotVector);
- IritFree((VoidPtr) RefTV -> VKnotVector);
- IritFree((VoidPtr) RefTV -> WKnotVector);
- RefTV -> UKnotVector = BspKnotCopy(TV -> UKnotVector,
- TV -> ULength + TV -> UOrder);
- RefTV -> VKnotVector = BspKnotCopy(TV -> VKnotVector,
- TV -> VLength + TV -> VOrder);
- RefTV -> WKnotVector = MergedKVt;
-
- RWLength = RefTV -> WLength;
-
- /* Update the control mesh */
- for (ODim = 0; ODim < ULength * VLength; ODim++) {
- int OIndex = ODim * TRIV_NEXT_U(TV),
- ROIndex = ODim * TRIV_NEXT_U(RefTV);
-
- for (j = IsNotRational; j <= MaxCoord; j++) {
- CagdRType
- *ROnePts = &RefTV -> Points[j][ROIndex],
- *OnePts = &TV -> Points[j][OIndex];
-
- for (i = 0;
- i < RWLength;
- i++, ROnePts += TRIV_NEXT_W(RefTV))
- CAGD_ALPHA_BLEND_STEP(A, i, OnePts,
- INFINITY,
- ROnePts, TRIV_NEXT_W(TV));
- }
- }
-
- BspKnotFreeAlphaCoef(A);
- break;
- default:
- TRIV_FATAL_ERROR(TRIV_ERR_DIR_NOT_VALID);
- break;
- }
- }
-
- BspKnotMakeRobustKV(RefTV -> UKnotVector,
- RefTV -> UOrder + RefTV -> ULength);
- BspKnotMakeRobustKV(RefTV -> VKnotVector,
- RefTV -> VOrder + RefTV -> VLength);
- BspKnotMakeRobustKV(RefTV -> WKnotVector,
- RefTV -> WOrder + RefTV -> WLength);
-
- return RefTV;
- }
-